package LianBiao;

public class lianBiaoList {
    private Node head;

    /**出初始化链表
     * 没有引用时 hdea=null
     * 头上没有节点时
     */
    public lianBiaoList() {
        head=null;
    }

    /**
     * 初始化链表（java版）
     */
    public void clearList(){
        head=null;
    }
    /**
     * 头部加节点
     */
    public void addAtHeader(int x){
        //x传给Node构造方法（参数只有int v的// ）  x存进v里  v（节点数据）被初始化了
        //此传给Node构造方法的下一个节点为空 next=null
        Node n=new Node(x);
        n.setNext(head);//Node 的对象n 吧head节点传给n
        head=n;
        /**
         * 所谓节点 立体图像暂为
         *  【数据v|头节点|下一节点=null】  【  |  】
         */
    }
    /**
     * 删除头部的节点
     */
    public void removeAtHeader() {
        if (head != null) {//在有head的时候
            head = head.getNext();//head等于上一个head
            /**
             * 所谓节点 立体图像暂为
             *  【数据v|头节点】  【数据|节点】  【数据|节点】 【数据|下一节点=null】  【  |  】
             *进行删除头部节点操作
             *                 【数据|头节点】 【数据|节点】 【数据|下一节点=null】  【  |  】
             *    ↑原头节点被删   ↑原头节点的一下个节点。↑头节点的下一节点。↑头节点的下下一节点
             */
        }
    }
        /**
         * 统计链表节点数量，链表遍历
         * count总数
         */

        public int getCount(){
            Node p=head;
//        用p代替head

            int count=0;
            while (p!=null){//下一个节点不为空，则进入循环
                count=count+1;//每次循环count自增1
                p=p.getNext();//每次循环p跳到下一个节点 ，直至下一个没有节点不会进入此循环
            }
            return count;//返回的count为节点数量
        }

    /**
     *     5查找指定节点
     * @param x
     * @return
     */
    public boolean search(int x) {
        Node p = head;
        /** 从头节点开始
         * //循化便遍历节点 直到找到指定节点 跳出循环
         */
        while (p != null) {
            if (p.getV() == x) {//查找指定节点   根据 存在节点里的数据查找
                break;
            }
            p = p.getNext();
        }
        if (p==null) {
//            空值判断
            return false;
        } else {
            return true;
        }
    }

    /**
     *  6尾部增加节点
     */

    public void addAtTall(int x){
        Node n=new Node(x);//
        Node p=head;
        if (head==null){//head==null时是 末尾为节点
            head=n;
            return;
//            末尾节点next=null;
            //在尾部加节点的方法
        }
        while (p.getNext()!=null){
            p=p.getNext();
        }


    }

    /**
     * 7。删除指定节点X,删除成功返回true,失败返回false
     * //        删除指定节点x(假设链表中的值不重复 ，删除集合里的数据)
     * //        步骤1.找到x这个节点，如果没有节点，直接返回，否则同步2
     * //        步骤2：找到当前节点p的前一个节点引用q,q.next=p.next
     *  上一个节点  就是指向x数据的节点    当前节点时指向x下一条数据的节点
     * @param x
     * @return
     */

    public boolean remove(int x) {
//        查找值为X的节点是否存在，如果存在,q记录节点的上一个节点的位置
//        此节点q的上一个节点 的下一个节点就会是值为x的节点，那么此时吧此节点q的下一个节点指向 x值节点的下一个节点，x值节点就没了呢
        /**
         * 删除节点图示  如：删除第二个节点（一共3个节点）
         *   删除前
         * 【数据1|头节点指向（2）】 【数据2|节点指向（3）】 【数据3|节点指向（null）】
         *   删除后 →原节点2消失 因为节点1直接指向节点3
         * 【数据1|头节点指向（3）】 【数据3|节点指向（null）】
         *   整理后
         * 【数据1|头节点指向（2）】 【数据2|节点指向（null）】
         */
        Node p = head;
        Node q = null;
//        当前节点的上一个节点引用
        while (p != null) {
//            开始节点
            if (p.getV() == x)
                break;
            q = p;//用q引用来存p节点

            p = p.getNext();//p=下一个节点
        }

        /**
         *    遍历结束所以节点，没有查到X  返回false
         */
        if (p == null) {
            return false;
        } else {
            /**
             * 否则查到了，返回    删除后ture
             */

//    p就是指向X的节点，q就是p的前一个节点
            q.setNext(p.getNext());//使q的下一个节点  ==  指向 p（指向x的节点）的下一个节点    p当前节点就没了
            return true;//此时q的一下一个节点 ==p

        }
    }
        /**
         *    按升序插入值为X的节点
         * //    8按升降序插入节点，以升序为例
         * //    有序链表，给定一个X按顺序插入X到链表1，3，5，7，9 X=2
         * //    步骤1找到X对应插入的节点位置，找到刚好大于X的节点p及其前一个节点q
         */

        public void insert(int x){
//        查到值刚好大于X的节点是否存在，如果存在，记录节点的上一个节点位置

            Node p=head;
            Node q=null;
//        X=10,1,2,3,4,5,10
            /**
             * 找到刚好大于x值得那个节点 的 上一个节点
             */
            while (p!=null){
//            开始节点
                if (p.getV()>x)
                    break;
                q=p;

                p=p.getNext();
            }
            /**
             *  判断一下此链表是不是空的
             *  如果是空的直接  用要插入的x值 初始化一下
             *  否则 再符合条件的上一个节点的下一个节点插入x值
             */
            if (p==null){
                    /**
                     * /如果p 的节点为null时
                     * 进行两个可能性的判断
                     * 如果头部节点为空，则说明链表未初始化
                     * 判断头部节点是不是为空，如果头部节点不为空证明初始化过了并且已经查到了最后一个节点
                     */
                    if (head==null){//判断一下时候没初始化

    //             addAtHeader(x);和下面的都行 都是初始化节点的方法 一个是调用写好的 一个是直接new一个
                        head=new Node(x);
                    }
                    else {
                        /**
                         * 再上一个节点的下一个节点插入
                         */
                        q.setNext(new Node(x));

                    }

            }
            else {
                /**
                 * p的节点不为空时
                 */
                Node n=new Node(x);
                n.setNext(p);// x值 Node构造方法 初始化节点数据 下一个节点为p
                q.setNext(n);//符合条件的上一个节点q的下一个节点指向n，然而上一条指令 n.setNext(p); n的下一个节点指向符合条件的节点p
                /**
                 * 综上所诉 连起来了
                 * 图示
                 * 数据x未插入使  设：数据2是符合条件的节点 数据1是符合条件的上一个节点
                 * 【数据1|节点指向（2）】 【数据2|节点指向（3）】
                 *  x值写入 ：连起来后
                 *  【数据1|节点指向（2）】 【数据x|节点指向（3）】 【数据2|节点指向（4）】
                 */
            }
        }

    public Node getHead() {

        return null;
    }
    public Iter iterator(){
        return new Iter(this);

    }
    /**
     * Iter类
     */
    class Iter {
        Node p;

        public Iter(lianBiaoList list) {
            p = list.getHead();

        }

        public boolean hasNext() {
            return p != null;
        }

        public int next() {
            int x = p.getV();
            p = p.getNext();

            return x;
        }
    }
}



